<template>
    <div style="text-align:left;">
        <div v-if="!mobile" class="xx-tools">
            <!-- <el-button size="mini" type="primary" @click="$router.push({path:'/'})">back</el-button> -->
            <!-- <el-dropdown style="margin-left:10px;">
                <el-button size="mini">import<i class="el-icon-arrow-down el-icon--right"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item>jquery</el-dropdown-item>
                    <el-dropdown-item>vue</el-dropdown-item>
                    <el-dropdown-item>bootstrap</el-dropdown-item>
                    <el-dropdown-item>elemeneui</el-dropdown-item>
                </el-dropdown-menu>
            </el-dropdown> -->
            <el-button type="primary" size="mini" @click="dialogFormVisible=true" icon="el-icon-plus">New Code</el-button>
            <el-input size="mini" v-model="item.title" placeholder="请输入内容" style="width:200px;margin-left:10px;"></el-input>
            <el-tooltip id="code_pic" class="item" effect="dark" content="鼠标点击一下，Ctrl+V粘贴图片，自动获取代码首页大图" placement="top-start">
            <i style="margin-left:10px;" class="el-icon-picture"></i>
            </el-tooltip>
            <span style="margin-left:10px;">
                <span style="font-size:15px;">Auto Preview：</span>
                <el-tooltip content="Switch Auto Preview" placement="top" >
                    <el-switch
                        v-model="auto"
                        active-color="#13ce66"
                        :active-value="true"
                        :inactive-value="false">
                    </el-switch>
                </el-tooltip>
            </span>
            <el-button type="success" size="mini" style="margin-left:10px;" @click="save" icon="el-icon-document-checked">Save</el-button>
            <el-button @click="goPreview" size="mini" type="success" style="margin-left:10px;" icon="el-icon-view">Preview</el-button>
            <!-- <el-button  size="mini" style="margin-left:10px;" @click="getImg(()=>{})">截图</el-button> -->
            <!-- @click="drawerNote=true" -->
            <el-button size="mini" type="info" style="margin-left:10px;" icon="el-icon-view" v-clipboard:success="onCopy" v-clipboard:copy="host+'/#/codeshow?snippet='+item.id">Preview Link</el-button>
            <el-button size="mini" type="info" style="margin:10px;" icon="el-icon-view" v-clipboard:success="onCopy" v-clipboard:copy="copyRealLink(item.type)">Real Link</el-button>
            <el-button  size="mini" style="margin-left:10px;" @click="showLayerIframe" icon="el-icon-paperclip">Notes</el-button>
        </div>
        <div v-if="!mobile" class="xx-edit" id="box">
            <!-- 电脑端 树形文件管理框 -->
            <div   @contextmenu.prevent="projectRightClick($event)" id="filesManager" class="filesManager">
                <el-tree :allow-drop="allowDrop" @node-drop="nodeDrop" draggable @node-contextmenu="rightClick"  @node-click="handleTreeNodeClick" ref="tree" style="background-color: rgb(30, 31, 38);height: 100%;color: white;" :data="filesManagerData" highlight-current>
                    <span class="custom-tree-node" slot-scope="{ node,data }">
                        <i v-if="data.type=='folder'" class="el-icon-folder"></i>
                        <i v-if="data.type=='file'" class="el-icon-document"></i>
                        <span>{{ node.label }}</span>
                    </span>
                </el-tree>
            </div>
            <!-- 收缩侧边栏1 -->
            <div id="middle_1" class="xx-middle">⋮</div>
            <div id="container" class="xx-editor" ></div>
            <!-- 收缩侧边栏2 -->
            <div id="middle_2" class="xx-middle">⋮</div>
            <div  class="xx-preview" style="position: relative;">
                <!--遮罩层 遮住iframe-->
                <div class="iframeDiv"></div>
                <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-modals" ref="preview_iframe" style="width:100%;height:100%;"></iframe>
            </div>
        </div>
        <div v-if="mobile">
            <el-tabs v-model="activeName" type="card">
                <el-tab-pane label="预览" name="preview">
                    <div class="xx-preview">
                        <iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms  allow-modals" ref="preview_iframe" style="width:100%;height:99%;"></iframe>
                    </div>
                </el-tab-pane>
                <el-tab-pane label="编辑" name="edit">
                    <div id="container" class="xx-editor"></div>
                </el-tab-pane>
                <el-tab-pane label="项目管理" name="project">
                    <!--手机端 树形文件管理框 -->
                    <div  id="filesManager">
                        <el-tree draggable @node-drop="nodeDrop" @node-click="handleTreeNodeClick" ref="tree" style="background-color: rgb(30, 31, 38);height: 100%;color: white;" :data="filesManagerData" highlight-current>
                            <span class="custom-tree-node" slot-scope="{ node,data }">
                                <i v-if="data.type=='folder'" class="el-icon-folder"></i>
                                <i v-if="data.type=='file'" class="el-icon-document"></i>
                                <span>{{ node.label }}</span>
                            </span>
                        </el-tree>
                    </div>
                </el-tab-pane>
                <el-tab-pane label="工具栏" name="tools">
                    <div class="xx-flex-column">
                        <el-button type="primary" size="mini" style="margin:10px;" @click="dialogFormVisible=true" icon="el-icon-plus">New Code</el-button>
                        <span style="margin:10px;">
                            <span style="font-size:15px;">Auto Preview：</span>
                            <el-tooltip content="Switch Auto Preview" placement="top" >
                                <el-switch
                                    v-model="auto"
                                    active-color="#13ce66"
                                    :active-value="true"
                                    :inactive-value="false">
                                </el-switch>
                            </el-tooltip>
                        </span>
                        <el-button type="success" size="mini" style="margin:10px;" @click="save" icon="el-icon-document-checked">Save</el-button>
                        <el-button @click="goPreview" size="mini" type="success" style="margin:10px;" icon="el-icon-view">Preview</el-button>
                        <el-button size="mini" type="info" style="margin:10px;" icon="el-icon-view" v-clipboard:success="onCopy" v-clipboard:copy="host+'/#/codeshow?snippet='+item.id">Preview Link</el-button>
                        <el-button size="mini" type="info" style="margin:10px;" icon="el-icon-view" v-clipboard:success="onCopy" v-clipboard:copy="copyRealLink(item.type)">Real Link</el-button>
                        <el-button  size="mini" style="margin:10px;" @click="showLayerIframe" icon="el-icon-paperclip">Notes</el-button>
                    </div>
                </el-tab-pane>
            </el-tabs>
        </div>
        <!-- <el-drawer
        title="片段笔记"
        :visible.sync="drawerNote"
        >
        <div style="overflow-y: scroll;height: calc(100vh - 55px);">
            <div style="margin: 10px;" v-html="item.note"></div>
        </div>
        </el-drawer> -->
        <!-- <el-dialog title="新建代码片段" :visible.sync="dialogFormVisible" :modal-append-to-body='false' >
          <el-form :model="form">
            <el-form-item label="代码片段标题">
              <el-input v-model="form.title" auto-complete="off"></el-input>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取 消</el-button>
            <el-button type="primary" @click="newCode">确 定</el-button>
          </div>
        </el-dialog> -->
        <el-dialog title="选择适合您的选项" :visible.sync="dialogFormVisible" :modal-append-to-body='false' >
            <el-card class="xx-box-card" v-bind:class="{ active: ProjectType==1}">
                <div @click="changeProjectType(1)">
                    <div class="title"><i class="el-icon-document"></i>单页应用(Single file)</div>
                    <div>单页应用，是仅提供一个html文件供您编写，适合小型前端或演示、教学使用。</div>
                </div>
            </el-card>
            <el-card  class="xx-box-card" v-bind:class="{ active: ProjectType==2}">
                <div @click="changeProjectType(2)">
                    <div class="title"><i class="el-icon-folder"></i>完整项目(Complete project)</div>
                    <div>完整项目，是提供一个目录，多文件编写，适合大型前端或应用生产环境。</div>
                </div>
            </el-card>
            <el-card  class="xx-box-card" v-bind:class="{ active: ProjectType==3}">
                <div @click="changeProjectType(3)">
                    <div class="title"><i class="el-icon-coin"></i>编程容器(CodeServer)</div>
                    <div>通过网页访问，提供整个虚拟Linux环境和代码编辑器供您开发支持多种语言。</div>
                </div>
            </el-card>
          <div slot="footer" class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取 消</el-button>
            <el-button type="primary" @click="newCodeDialog">确 定</el-button>
          </div>
        </el-dialog>
        <!-- <canvas id="canvas" style="border: 1px solid black;"></canvas> -->
        <el-menu
            v-show="menu"
            id="menu"
            text-color="#000"
            active-text-color="#000"
        >
            <el-menu-item @click="rightMenuClick(item)" v-for="(item,i) in menuData" class="menuItem" v-bind:key="i">
                <span slot="title">{{item.title}}</span>
            </el-menu-item>
        </el-menu>
        <el-dialog :title="dialogForm2.dialogTitle" :visible.sync="dialogForm2.dialogFormVisible" :modal-append-to-body='false' >
          <el-form :model="dialogForm2.form">
            <el-form-item v-for="(item,i) in dialogForm2.dialogFormItems" :label="item.label" v-bind:key="i">
              <el-input v-model="dialogForm2.form[item.model]" auto-complete="off"></el-input>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="dialogForm2.dialogFormVisible = false">取 消</el-button>
            <el-button type="primary" @click="projectOp(dialogForm2.data,dialogForm2.form,rightClickSelectNode)">确 定</el-button>
          </div>
        </el-dialog>
    </div>

</template>

<script>
import * as monaco from 'monaco-editor'
import html2canvas from 'html2canvas'
import Axios from 'axios'
import API from '../api'
import Note from '../views/Note.vue'

// import rasterizeHTML from 'rasterizeHTML'
export default {
    name: 'VsCode',
    props: {
        item: {
            type: Object,
            default: () => { return {} }
        },
        value: {
            type: String,
            default: ''
        },
        filesManagerData: {
            type: Array,
            default: () => { return [] }
        }
    },
    data() {
        return {
            rightClickSelectNode: null,
            ProjectType: 1,
            selectNode: null,
            host: '',
            auto: false,
            url: '',
            mobile: false,
            monacoEditor: null,
            activeName: 'preview',
            drawerNote: false,
            form: {},
            dialogFormVisible: false,
            menu: false,
            projectMenu: false,
            menuData: [],
            // 项目右键菜单
            menuData_project: [
                { title: '上传文件', click: '' },
                { title: '上传项目[?]', click: '' },
                { title: '新建文件', click: '' },
                { title: '新建文件夹', click: '' }
            ],
            // 目录右键菜单
            menuData_folder: [
                { title: '上传文件', click: '' },
                { title: '上传项目[?]', click: '' },
                { title: '新建文件', click: '' },
                { title: '新建文件夹', click: '' },
                { title: '重命名', click: '' },
                { title: '删除', click: '' }
            ],
            // 文件右键菜单
            menuData_file: [
                { title: '重命名', click: '' },
                { title: '复制直链', click: '' },
                { title: '复制相对路径', click: '' },
                { title: '生成标签代码', click: '' },
                { title: '删除', click: '' }

            ],
            // 通用对话框配置
            dialogForm2: {
                dialogTitle: '请输入',
                dialogFormVisible: false,
                form: {},
                dialogFormItems: [
                    { label: '新建文件的文件名', model: 'name' }
                ],
                data: {}
            }
        }
    },
    watch: {
        value() {
            this.monacoEditor.getModel().setValue(this.value)
            this.goPreview()
        },
        item() {
            this.code_pic_base64 = this.item.img
        }
    },
    activated() {
        // 用户直接进来
        // 默认html语言
        this.$nextTick(() => {
            monaco.editor.setModelLanguage(this.monacoEditor.getModel(), 'html')
            this.goPreview()
            this.fileType = ''
        })
    },
    computed: {

    },
    mounted() {
        this.host = window.location.host
        // 窗口变化时 去除拖拽赋值的宽高
        window.onresize = () => {
            // 文件项目浏览器
            var div1 = document.getElementById('filesManager')
            // 收缩侧边栏1
            var resize = document.getElementById('middle_1')
            // 编辑器
            var div2 = document.getElementsByClassName('xx-editor')[0]
            // 收缩侧边栏2
            var resize2 = document.getElementById('middle_2')
            // 预览器
            var div3 = document.getElementsByClassName('xx-preview')[0]
            div1.style.width = '10%'
            resize.style.left = 0
            div2.style.width = '50%'
            resize2.style.left = 0
            div3.style.width = 'calc(40% - 30px)'
            console.log('去除高度')
        }
        this.changeIframeDivStyle('none')
        // 开启自由调整宽度
        this.dragControllerMiddle1()
        document.onkeydown = (event) => {
            const key = window.event.keyCode
            if (key == 83 && event.ctrlKey) { //= = 83 && event.ctrlKey
                window.event.preventDefault() // 关闭浏览器快捷键
                this.save()
            }
        }
        if (document.documentElement.clientWidth <= 600) {
            this.mobile = true
        }
        // DOM进行操作的nextTick
        this.$nextTick(function() {
            this.monacoEditor = monaco.editor.create(document.getElementById('container'), {
                language: 'html',
                value: this.value,
                theme: 'vs-dark',
                automaticLayout: true

            })
            this.monacoEditor.onDidChangeModelContent(() => {
                this.throttle(() => {
                    if (this.auto) {
                        this.goPreview()
                    }
                }, 1000)
            })
            // 动态更改高亮语言demo
            // monaco.editor.setModelLanguage(this.monacoEditor.getModel(),"css")
        })
        this.pasteEventListener()
    },
    methods: {
        /**
             * 监听图片按钮粘贴事件
             * @date 2021-06-12
             * @returns {any}
             */
        pasteEventListener() {
            // 粘贴获取截图
            const code_pic = document.getElementById('code_pic')
            code_pic.addEventListener('paste', (event) => {
                const items = event.clipboardData && event.clipboardData.items
                let file = null
                if (items && items.length) {
                    // 检索剪切板items
                    for (let i = 0; i < items.length; i++) {
                        if (items[i].type.indexOf('image') !== -1) {
                            file = items[i].getAsFile()
                            // 此时file就是剪切板中的图片文件
                            const code_pic_reader = new FileReader()
                            // 解析成base64格式
                            code_pic_reader.readAsDataURL(file)
                            code_pic_reader.onload = () => {
                                this.code_pic_base64 = code_pic_reader.result
                                this.$message({
                                    message: '图片获取成功，请记得点击保存按钮。',
                                    type: 'success'
                                })
                            }
                            break
                        }
                    }
                }
            })
        },
        changeProjectType(type) {
            this.ProjectType = type
            console.log(this.ProjectType)
        },
        // 新建代码片段弹窗
        newCodeDialog() {
            this.dialogForm2 = {
                dialogTitle: '请输入',
                dialogFormVisible: true,
                form: {},
                dialogFormItems: [
                    { label: '新建项目的标题', model: 'title' }
                ],
                data: {
                    item: { title: '新建项目' },
                    ProjectType: this.ProjectType
                }
            }
        },
        // 右键点击菜单事件
        rightMenuClick(item) {
            console.log(item)
            switch (item.title) {
            case '新建文件':
                this.dialogForm2 = {
                    dialogTitle: '请输入',
                    dialogFormVisible: true,
                    form: {},
                    dialogFormItems: [
                        { label: '新建文件的文件名', model: 'name' }
                    ],
                    data: {
                        item: item
                    }
                }
                break
            case '新建文件夹':
                this.dialogForm2 = {
                    dialogTitle: '请输入',
                    dialogFormVisible: true,
                    form: {},
                    dialogFormItems: [
                        { label: '新建文件夹的文件名', model: 'name' }
                    ],
                    data: {
                        item: item
                    }
                }
                break
            case '重命名':
                this.dialogForm2 = {
                    dialogTitle: '请输入新的名称',
                    dialogFormVisible: true,
                    form: { name: this.rightClickSelectNode.label },
                    dialogFormItems: [
                        { label: '名称', model: 'name' }
                    ],
                    data: {
                        item: item
                    }
                }
                break
            case '删除':
                this.dialogForm2 = {
                    dialogTitle: '真的要删除吗？',
                    dialogFormVisible: true,
                    form: { delete: true },
                    dialogFormItems: [],
                    data: {
                        item: item
                    }
                }
                break
            case '复制直链':
                this.doCopy(API.getServer() + 'common/getSnippetProjectFile/' + this.rightClickSelectNode.path)
                break
            case '复制相对路径':
                this.doCopy(this.getRelativePath(this.rightClickSelectNode.path))
                break
            case '生成标签代码':
                this.makeTag(this.rightClickSelectNode)
                break
            default:
                break
            }
        },
        // 判断是否允许拖拽
        allowDrop(darggingNode, dropNode, type) {
            if (dropNode.data.type == 'file') {
                return type == 'next'
            } else {
                return type
            }
        },
        // 拖拽移动文件或文件夹
        nodeDrop(darggingNode, dropNode, type) {
            let path = ''
            let new_path = ''
            if (type == 'inner') {
                console.log(darggingNode.data.path, dropNode.data.path + darggingNode.data.path.substring(darggingNode.data.path.lastIndexOf('/')), type)
                path = darggingNode.data.path
                new_path = dropNode.data.path + darggingNode.data.path.substring(darggingNode.data.path.lastIndexOf('/'))
            } else {
                console.log(darggingNode.data.path, dropNode.data.path.substring(0, dropNode.data.path.lastIndexOf('/')) + darggingNode.data.path.substring(darggingNode.data.path.lastIndexOf('/')), type)
                path = darggingNode.data.path
                new_path = dropNode.data.path.substring(0, dropNode.data.path.lastIndexOf('/')) + darggingNode.data.path.substring(darggingNode.data.path.lastIndexOf('/'))
            }
            this.axios(API.snippetProject.SnippetProjectMoveFile(path, new_path)).then(() => {
                this.$message({
                    message: '移动成功。',
                    type: 'success'
                })
                // 更新树形框
                this.$root.$emit('getSnippetProject')
                this.dialogForm2.dialogFormVisible = false
            }).catch((e) => {
                this.$message.error(e)
            })
        },
        // 处理右键菜单弹窗业务代码
        projectOp(data, form, rightClickSelectNode) {
            console.log(data, form, rightClickSelectNode)
            var path
            switch (data.item.title) {
            case '新建项目':
                if (form.title == null || form.title == undefined) {
                    this.$message.error('标题不能为空。')
                    return
                }
                // 单页应用
                if (data.ProjectType == 1) {
                    this.newCode(form.title)
                }
                // 完整项目
                if (data.ProjectType == 2) {
                    this.newProjectCode(form.title)
                }
                // 编程容器
                if (data.ProjectType == 3) {
                    this.$message.error('暂未支持编程容器，当前开发进度百分之0%。')
                }
                this.dialogForm2.dialogFormVisible = false
                break
            case '删除':
                path = rightClickSelectNode.path
                this.axios(API.snippetProject.SnippetProjectDelFile(path)).then(() => {
                    this.$message({
                        message: '删除成功。',
                        type: 'success'
                    })
                    // 更新树形框
                    this.$root.$emit('getSnippetProject')
                    this.dialogForm2.dialogFormVisible = false
                }).catch((e) => {
                    this.$message.error(e)
                })
                break
            case '新建文件夹':
                console.log(form)
                if (form.name == null || form.name == '') {
                    this.$message.error('文件夹名不能为空。')
                    return
                }
                path = this.item.id + '/' + form.name
                if (rightClickSelectNode != null) {
                    path = rightClickSelectNode.path + '/' + form.name
                }
                this.axios(API.snippetProject.SnippetProjectNewDirectory(path)).then(() => {
                    this.$message({
                        message: '新建成功。',
                        type: 'success'
                    })
                    // 更新树形框
                    this.$root.$emit('getSnippetProject')
                    this.dialogForm2.dialogFormVisible = false
                }).catch((e) => {
                    this.$message.error(e)
                })
                break
            case '新建文件':
                console.log(form)
                path = this.item.id
                if (form.name == null || form.name == '') {
                    this.$message.error('文件名不能为空。')
                    return
                }
                if (rightClickSelectNode != null) {
                    path = rightClickSelectNode.path
                }
                console.log(path)
                console.log(this.item.id)
                this.axios(API.snippetProject.SnippetProjectNewFile(path, form.name)).then(() => {
                    this.$message({
                        message: '新建成功。',
                        type: 'success'
                    })
                    // 更新树形框
                    this.$root.$emit('getSnippetProject')
                    this.dialogForm2.dialogFormVisible = false
                }).catch((e) => {
                    this.$message.error(e)
                })
                break
            case '重命名':
                console.log(form)
                var new_path = rightClickSelectNode.path.substring(0, rightClickSelectNode.path.lastIndexOf('/') + 1) + form.name
                this.axios(API.snippetProject.SnippetProjectReName(rightClickSelectNode.path, new_path)).then(() => {
                    this.$message({
                        message: '重命名成功。',
                        type: 'success'
                    })
                    // 更新树形框
                    this.$root.$emit('getSnippetProject')
                    this.dialogForm2.dialogFormVisible = false
                }).catch((e) => {
                    this.$message.error(e)
                })
                break

            default:
                break
            }
        },
        // 获取相对路径
        getRelativePath(path) {
            // 去除代码片段id
            var index = path.indexOf('/')
            var path2 = path.substring(index + 1)
            return path2
        },
        // 生成标签代码
        makeTag(node) {
            var type = node.label.split('.').pop()
            console.log(type)
            switch (type) {
            case 'jpg':
            case 'gif':
            case 'bmp':
            case 'png':
                this.doCopy(`<img src="${this.getRelativePath(this.rightClickSelectNode.path)}" />`)
                break
            case 'js':
                /* eslint-disable-next-line */
                        this.doCopy(`<script src="${this.getRelativePath(this.rightClickSelectNode.path)}"><\/script>`)
                break
            case 'css':
                this.doCopy(`<link href="${this.getRelativePath(this.rightClickSelectNode.path)}" rel="stylesheet" >`)
                break
            case 'html':
                /* eslint-disable-next-line */
                        this.doCopy(`<a href="${this.getRelativePath(this.rightClickSelectNode.path)}" >${node.label}<\/a>`)
                break
            default:
                break
            }
        },
        doCopy(val) {
            const _this = this
            this.$copyText(val).then(function() {
                _this.$message({
                    message: '复制成功',
                    type: 'success'
                })
            }, function() {
                _this.$message.error('复制失败')
            })
        },
        copyRealLink(type) {
            switch (type) {
            case 0:
                return API.getServer() + 'common/SnippetHtml/' + this.item.id
            case 1:
                return API.getServer() + 'common/getSnippetProjectFile/' + this.item.id + '/index.html'


            default:
                return '┗|｀O′|┛ 嗷~~生成链接失败！帮你复制了主站链接：codeshare.diyxi.top'
            }
        },
        projectRightClick(event) {
            this.menu = true
            const projectMenu = document.querySelector('#menu')
            this.menuData = this.menuData_project
            /* 菜单定位基于鼠标点击位置 */
            projectMenu.style.position = 'fixed'
            projectMenu.style.left = event.clientX + 'px'
            projectMenu.style.top = event.clientY + 'px'
            projectMenu.style.width = '150px'
            document.addEventListener('click', () => {
                this.menu = false
            })
            this.rightClickSelectNode = null
        },
        rightClick(event, data) {
            if (data.type == 'file') {
                this.menuData = this.menuData_file
            } else {
                this.menuData = this.menuData_folder
            }
            this.menu = true// 让菜单显示
            const menu = document.querySelector('#menu')
            /* 菜单定位基于鼠标点击位置 */
            menu.style.position = 'fixed'
            menu.style.left = event.clientX + 'px'
            menu.style.top = event.clientY + 'px'
            menu.style.width = '150px'
            document.addEventListener('click', () => {
                this.menu = false
            })
            this.rightClickSelectNode = data
        },
        handleTreeNodeClick(data) {
            this.projectMenu = false// 让菜单不显示
            this.menu = false
            console.log(data)
            this.selectNode = data
            const code_types = ['css', 'javascript', 'html']
            const pic_types = ['jpg', 'jpeg', 'png']
            this.fileType = this.getFileType(data.label)
            console.log(pic_types.indexOf(this.getFileType(data.label)))
            if (data.type == 'file') {
                // 判断是否为图片类文件
                if (pic_types.indexOf(this.getFileType(data.label)) > -1) {
                    this.$root.$emit('updateSnippetValue', `<img src="${data.path.substring(data.path.indexOf('/') + 1)}" />`)
                    monaco.editor.setModelLanguage(this.monacoEditor.getModel(), 'html')
                    return
                }
                // 判断是否为代码类文件
                if (code_types.indexOf(this.getFileType(data.label)) < 0) {
                    this.$message({
                        message: data.label + '，该文件暂时不支持预览和加载。',
                        type: 'info'
                    })
                    return
                }
                console.log('加载文件中……')
                this.axios(API.snippetProject.getSnippetProjectFile(data.path)).then(res => {
                    console.log(res)
                    this.$root.$emit('updateSnippetValue', res.data)
                    monaco.editor.setModelLanguage(this.monacoEditor.getModel(), this.getFileType(data.label))
                }).catch((e) => {
                    console.log(e)
                })
            }
        },
        // 传入文件名称，获取后缀
        getFileType(fileName) {
            var type = fileName.split('.').pop()
            switch (type) {
            case 'js':
                return 'javascript'
            default:
                return type
            }
        },
        onCopy() {
            this.$message({
                message: '复制链接成功！',
                type: 'success'
            })
        },
        save() {
            if (this.item.id == undefined) {
                this.$message.error('请新建项目或打开项目后再保存。【警告会丢失当前页信息。】')
                return
            }
            switch (this.item.type) {
            case 0:
                this.onlyHtmlSave()
                break
            case 1:
                this.projectSave()
                break
            default:
                break
            }
        },
        projectSave() {
            if (this.selectNode == null) {
                this.$message({
                    message: '没有任何文件被打开。',
                    type: 'info'
                })
                return
            }
            const code = this.monacoEditor.getValue()
            const pic_types = ['jpg', 'jpeg', 'png']
            if (pic_types.indexOf(this.fileType) > -1) {
                this.$message.error('图片只能预览，无法修改。')
                return
            }
            this.axios(API.snippetProject.updateSnippetProjectFile(this.selectNode.path, code)).then(() => {
                if (this.fileType == 'html') {
                    // 获取截图并调用上传事件
                    // 暂定 取消截图功能
                    // 暂定 用户手动截图上传
                    this.$emit('updateSnippet', '', this.code_pic_base64)
                    this.goPreview()
                    // this.getImg((e)=>{

                    // })
                } else {
                    this.goPreview()
                    this.$message({
                        message: '文件保存成功！',
                        type: 'success'
                    })
                }
            }).catch((e) => {
                this.$message.error(e)
            })
        },
        onlyHtmlSave() {
            // 获取截图并调用上传事件
            // 暂定 取消截图功能
            // 暂定 用户手动截图上传
            this.$emit('updateSnippet', this.monacoEditor.getValue(), this.code_pic_base64)
            this.goPreview()
            // this.getImg((e)=>{

            // })
        },
        showLayerIframe() {
            let xx_area = ['70%', '80%']
            if (this.$store.state.mobile) {
                xx_area = ['100%', '100%']
            }
            this.$layer.iframe({
                content: {
                    content: Note, // 传递的组件对象
                    parent: this, // 当前的vue对象
                    data: {
                        note: this.item.note
                    }// props
                },
                offset: 'auto',
                shade: false,
                area: xx_area,
                title: '代码片段笔记',
                resize: true,
                cancel: () => { // 关闭事件

                }
            })
            if (!this.$store.state.mobile) {
                var layerDiv = document.getElementsByClassName('vl-notify')[0]
                if (layerDiv != null) {
                    layerDiv.onmousedown = () => {
                        this.changeIframeDivStyle('block')
                    }
                    layerDiv.onmouseup = () => {
                        this.changeIframeDivStyle('none')
                    }
                }
            }
        },
        newCode(title) {
            this.dialogFormVisible = false
            const content = this.monacoEditor.getValue()
            this.axios(API.snippet.insertSnippet(title, content)).then(res => {
                this.$router.push({ path: '/myvscode', query: { snippet: res.data.data } })
                this.$root.$emit('cleanSnippetInfo')
                this.$root.$emit('getSnippetInfo')
            }).catch((e) => {
                this.$message.error(e)
            })
        },
        newProjectCode(title) {
            this.dialogFormVisible = false
            this.axios(API.snippetProject.insertSnippetProject(title)).then(res => {
                this.$router.push({ path: '/myvscode', query: { snippet: res.data.data } })
                this.$root.$emit('cleanSnippetInfo')
                this.$root.$emit('getSnippetInfo')
            }).catch((e) => {
                this.$message.error(e)
            })
        },
        changeIframeDivStyle(display) {
            var iframeDiv = document.getElementsByClassName('iframeDiv')
            iframeDiv[0].style.display = display
        },
        dragControllerMiddle1() {
            var box = document.getElementsByClassName('xx-edit')[0]
            // 文件项目浏览器
            var div1 = document.getElementById('filesManager')
            // 收缩侧边栏1
            var resize = document.getElementById('middle_1')
            // 编辑器
            var div2 = document.getElementsByClassName('xx-editor')[0]
            // 收缩侧边栏2
            var resize2 = document.getElementById('middle_2')
            // 预览器
            var div3 = document.getElementsByClassName('xx-preview')[0]

            // console.log(div1,resize,div2,resize2,div3,box)
            // 收缩侧边栏1被鼠标按下
            resize.onmousedown = (e) => {
                // 获取鼠标X坐标
                var startX = e.clientX
                // 获取侧边栏宽度
                var asideWidth = document.getElementsByClassName('xx-aside')[0].clientWidth
                // 获取收缩栏侧边距离 减去侧边导航栏宽度 减去main下的padding宽度
                resize.left = resize.offsetLeft - asideWidth - 20
                // 鼠标拖动事件
                document.onmousemove = function(e) {
                    // 结束时鼠标坐标
                    var endX = e.clientX
                    // 侧边栏位置+鼠标移动距离
                    var moveLen = resize.left + (endX - startX)
                    // 设置resize位置
                    resize.style.left = moveLen
                    // 最小宽度
                    if (moveLen < 50) {
                        moveLen = 50
                    }
                    // 最大宽度
                    var maxT = box.clientWidth - resize.offsetWidth - div3.clientWidth
                    if (moveLen > maxT - 50) {
                        moveLen = maxT - 50
                    }
                    // 设置div1的宽度
                    div1.style.width = moveLen + 'px'
                    // 设置div2的宽度
                    div2.style.width = (box.clientWidth - moveLen - 30 - div3.clientWidth) + 'px'
                }
                // 鼠标松开事件
                document.onmouseup = () => {
                    document.onmousemove = null
                    document.onmouseup = null
                    resize.releaseCapture && resize.releaseCapture() // 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
                }
                resize.setCapture && resize.setCapture() // 该函数在属于当前线程的指定窗口里设置鼠标捕获
                return false
            }
            // 收缩侧边栏2被鼠标按下
            resize2.onmousedown = (e) => {
                // 开启iframe遮罩
                this.changeIframeDivStyle('block')
                // 获取鼠标X坐标
                var startX = e.clientX
                // 获取侧边栏宽度
                var asideWidth = document.getElementsByClassName('xx-aside')[0].clientWidth
                // 获取收缩栏侧边距离 减去侧边导航栏宽度 减去main下的padding宽度 减去div1的宽度
                resize2.left = resize2.offsetLeft - asideWidth - 32 - div1.clientWidth
                // 鼠标拖动事件
                document.onmousemove = function(e) {
                    // 结束时鼠标坐标
                    var endX = e.clientX
                    // 鼠标移动距离
                    var moveLen = resize2.left + (endX - startX)
                    // 设置resize2位置
                    resize2.style.left = moveLen
                    // 最小宽度
                    if (moveLen < 50) {
                        moveLen = 50
                    }
                    // 最大宽度
                    var maxT = box.clientWidth - resize2.offsetWidth - div1.clientWidth
                    if (moveLen > maxT - 50) {
                        moveLen = maxT - 50
                    }
                    // 设置div2的宽度
                    div2.style.width = moveLen + 'px'
                    // 设置div3的宽度
                    div3.style.width = (box.clientWidth - moveLen - 30 - div1.clientWidth) + 'px'
                }
                // 鼠标松开事件
                document.onmouseup = () => {
                    // 关闭iframe遮罩
                    this.changeIframeDivStyle('none')
                    document.onmousemove = null
                    document.onmouseup = null
                    resize.releaseCapture && resize.releaseCapture() // 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
                }
                resize.setCapture && resize.setCapture() // 该函数在属于当前线程的指定窗口里设置鼠标捕获
                return false
            }
        },
        BlobtoBase64(blob) {
            return new Promise((res, rej) => {
                const reader = new FileReader()
                reader.readAsDataURL(blob)
                reader.onload = () => res(reader.result)
                reader.onerror = () => rej(reader)
            })
        },
        // 截图方法
        async getImg(callback) {
            const loading = this.$loading({
                lock: true,
                text: '正在保存……',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.7)'
            })
            // //获取页面canvas
            // var canvas =document.getElementById("canvas");
            // //把iframe宽度赋值给canvas
            // canvas.width=this.$refs.preview_iframe.offsetWidth
            // //把iframe高度赋值给canvas
            // canvas.height=this.$refs.preview_iframe.offsetHeight
            // //获取代码，渲染图片
            // rasterizeHTML.drawHTML(this.$refs.preview_iframe.contentWindow.document.documentElement.innerHTML,canvas).then(()=>{
            //     //执行回调
            //     callback(canvas.toDataURL('image/jpeg'))
            // })
            try {
                for (const img of this.$refs.preview_iframe.contentWindow.document.images) {
                    // img.src=""
                    // console.log(img.src)
                    try {
                        const blob = (await Axios.get(API.getServer() + 'common/getImageByHeader?src=' + img.src, { responseType: 'blob' })).data
                        const base64Res = await this.BlobtoBase64(blob)
                        img.src = base64Res
                    } catch (error) {
                        img.src = ''
                    }
                }
            } catch (error) {
                console.log('图片无法获取。')
            }

            html2canvas(
                this.$refs.preview_iframe.contentWindow.document.documentElement,
                {
                    backgroundColor: null, // 画出来的图片有白色的边框,不要可设置背景为透明色（null）
                    useCORS: true, // 支持图片跨域
                    // allowTaint: true, //允许跨域（图片跨域相关）
                    scale: 1, // 设置放大的倍数
                    foreignObjectRendering: true
                }
            ).then(canvas => {
                loading.close()
                callback(canvas.toDataURL('image/jpeg'))
            })
        },
        throttle(method, time) {
            clearTimeout(this.preview)
            this.preview = setTimeout(method, time)
        },
        // getMockData(){
        //     this.loading = this.$loading({
        //         lock: true,
        //         text: 'Loading',
        //         spinner: 'el-icon-loading',
        //         background: 'rgba(0, 0, 0, 0.7)'
        //     });

        //     this.axios.get('/mock/default.html').then(res=>{
        //         console.log(res)
        //         this.monacoEditor.getModel().setValue(res.data);
        //         this.loading.close();
        //     })
        // },
        goPreview() {
            this.$refs.preview_iframe.src = '/mock/default.html'
            let base = `<base href="${API.getServer()}common/getSnippetProjectFile/${this.item.id}/" />`
            console.log(this.item.type)
            if (this.$route.query.url != null || this.item.type == 0) {
                base = ''
            }
            let content = ''
            switch (this.fileType) {
            case 'javascript':
                /* eslint-disable-next-line */
                        content='<h1 style="text-align: center;color: brown;line-height: 90vh;">文件无法预览</h1>'
                break
            case 'css':
                content = '<h1 style="text-align: center;color: brown;line-height: 90vh;">文件无法预览</h1>'
                break
            default:
                content = base + this.monacoEditor.getValue()
                break
            }
            setTimeout(() => {
                this.$refs.preview_iframe.contentWindow.document.write(content) // 动态写入返回页面到iframe
                this.$refs.preview_iframe.contentWindow.document.close()
            }, 500)
        }
    }
}
</script>

<style scoped>
    #code_pic:focus{
        color: #409EFF;
    }
    .active{
        background-color: burlywood;
    }
    .xx-box-card{
        cursor: pointer;
        margin:10px;
    }
    .xx-box-card .title{
        margin:5px;
        font-size: 17px;
        font-weight: bolder;
    }
    .iframeDiv {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 10;
    filter: alpha(opacity=0);
    opacity: 0;
    background: transparent;
    margin-top: 30px;
    /*display: none;*/
    }
    .xx-edit{
        display: flex;
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
    }
    .filesManager{
        width:10%;
        background-color: rgb(30, 31, 38);
        height: calc(100vh - 150px);
    }
    .xx-editor{
        height:calc(100vh - 150px);
        width:50%;
    }
    .xx-preview{
        height:calc(100vh - 150px);
        width:calc(40% - 30px);
        /* margin:10px; */
    }
    .xx-tools{
        margin-bottom: 10px;
    }
    .xx-middle{
        cursor: col-resize;
        height: 100%;
    }
    .xx-flex-column{
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-content: center;
    }
    @media screen and (max-width: 600px) {
        .xx-edit{
            display: flex;
            flex-direction: column;
        }
        .xx-editor{
            height:calc(100vh - 101px);
            width:99%;
            margin:0px;
        }
        .xx-preview{
            height:calc(100vh - 101px);
            width:99%;margin:0px;
        }
        .xx-tools{
            width: 90vw;white-space: nowrap;overflow-x: auto;
        }

    }
</style>
